'use strict';
var vk; // 全局vk实例
// 涉及的表名
const dbName = require("../../../dao/config.js");

var db = uniCloud.database(); // 全局数据库引用
var _ = db.command; // 数据库操作符
var $ = _.aggregate; // 聚合查询操作符
/**
 * 权限注意：访问以下链接查看
 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#内置权限
 */
var cloudObject = {
	isCloudObject: true, // 标记为云对象模式
	/**
	 * 请求前处理，主要用于调用方法之前进行预处理，一般用于拦截器、统一的身份验证、参数校验、定义全局对象等。
	 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#before-预处理
	 */
	_before: async function() {
		vk = this.vk; // 将vk定义为全局对象
		// let { customUtil, uniID, config, pubFun } = this.getUtil(); // 获取工具包
	},
	/**
	 * 请求后处理，主要用于处理本次调用方法的返回结果或者抛出的错误
	 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#after-后处理
	 */
	_after: async function(options) {
		let { err, res } = options;
		if (err) {
			return; // 如果方法抛出错误，直接return;不处理
		}
		return res;
	},
	/**
	 * 获取订单列表
	 * @url admin/business/sys.order.getList 前端调用的url参数地址
	 */
	getList: async function(data) {
		let res = { code: 0, msg: '' };
		let { formData={} } = data;
		let { status } = formData;
		let whereJson = {};
		if (status === 100) {
			// 查询待核销的订单
			whereJson = {
				status: 4,
				order_type: 1
			};
		} else if (status === 101) {
			// 查询已核销的订单
			whereJson = {
				status: _.gt(4),
				order_type: 1
			};
		}
		// 业务逻辑开始-----------------------------------------------------------
		res = await vk.daoCenter.orderDao.getTableData({
			data,
			whereJson,
			foreignDB: [{
				dbName: dbName.user, // 副表名
				localKey: $.arrayElemAt(['$inviter_uid', 0]), // 主表外键字段名
				foreignKey: "_id", // 副表外键字段名
				as: "inviterUserInfo",
				limit: 1, // 当limit = 1时，以对象形式返回，否则以数组形式返回
				fieldJson:{ token: false,password: false },
			}]
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 订单状态分组
	 * @url admin/business/sys.order.groupCountOrderForStatus 前端调用的url参数地址
	 */
	groupCountOrderForStatus: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		res.group = await vk.daoCenter.orderDao.groupCountOrderForStatus({
			status: _.in([-2, 0, 1, 2, 3])
		}, data);
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 订单准备发货或取消准备发货
	 * @url admin/business/sys.order.updateReadySend 前端调用的url参数地址
	 */
	updateReadySend: async function(data) {
		let res = { code: 0, msg: '' };
		let { uid } = this.getClientInfo();
		// 业务逻辑开始-----------------------------------------------------------
		let {
			ids, // 需要修改的订单id列表
			mode, // 默认 1 准备发货 -1 取消准备发货
		} = data;
		// 参数非空检测
		if (vk.pubfn.isNullOne(ids, mode)) {
			return { code: -1, msg: '参数错误' };
		}
		let dataStatus = (mode === 1) ? 2 : 1;
		let whereStatus = (dataStatus === 2) ? 1 : 2;
		// 执行数据库API请求
		res.num = await vk.daoCenter.orderDao.update({
			whereJson: {
				_id: _.in(ids),
				status: whereStatus
			},
			dataJson: {
				status: dataStatus
			}
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 修改订单收货信息
	 * @url admin/business/sys.order.updateReceiverInfo 前端调用的url参数地址
	 */
	updateReceiverInfo: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id,
			address,
			position,
			receiver_name,
			receiver_mobile,
		} = data;
		// 参数非空检测
		let nullKey = vk.pubfn.isNullOneByObject({ _id, address, position, receiver_name, receiver_mobile });
		if (nullKey) return { code: -1, msg: '参数 ' + nullKey + ' 不能为空' };
		position.address = address;
		let formatted_address;
		try {
			formatted_address = `${position.province.name}${position.city.name}${position.area.name}${position.address}`;
		} catch (err) {
			return { code: -1, msg: '地址参数错误' };
		}
		res.info = await vk.daoCenter.orderDao.updateAndReturn({
			whereJson: {
				_id
			},
			dataJson: {
				'express_info.position': position,
				'express_info.formatted_address': formatted_address,
				'express_info.receiver_name': receiver_name,
				'express_info.receiver_mobile': receiver_mobile
			}
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 修改订单备注
	 * @url admin/business/sys.order.updateRemark 前端调用的url参数地址
	 */
	updateRemark: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id, // 订单id
			seller_remark, // 商家备注(用户可见)
			seller_note, // 商家备注(用户不可见)
		} = data;
		// 参数非空检测
		if (vk.pubfn.isNullOne(_id)) {
			return { code: -1, msg: '参数错误' };
		}
		res.num = await vk.daoCenter.orderDao.updateById({
			id: _id,
			dataJson: {
				seller_remark,
				seller_note,
			}
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},

	/**
	 * 订单发货
	 * @url admin/business/sys.order.orderSend 前端调用的url参数地址
	 */
	orderSend: async function(data) {
		let res = { code: 0, msg: '' };
		let { uid } = this.getClientInfo();
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id, // 订单ID
			express_name, // 快递公司名称
			express_no, // 快递单号
			send_name, // 发货人名称
			send_mobile, // 发货人手机号
			tips = [], // 用户设置提醒消息
			goods_sku_list, // 发货信息数据
		} = data;
		// 参数非空检测
		let nullKey = vk.pubfn.isNullOneByObject({ _id, express_name, express_no });
		if (nullKey) return { code: -1, msg: '参数 ' + nullKey + ' 不能为空' };

		let update_send_time = false;
		let send_sms = false;
		if (tips) {
			if (tips.indexOf('更新发货时间') > -1) {
				update_send_time = true;
			}
			if (tips.indexOf('发送短信提醒') > -1) {
				send_sms = true;
			}
		}
		// 订单发货操作
		res = await vk.daoCenter.orderDao.orderSend({
			_id, // 订单ID
			express_name, // 快递公司名称
			express_no, // 快递单号
			send_name, // 发货人名称
			send_mobile, // 发货人手机号
			goods_sku_list, // 发货信息数据 { _id, send_num } 若 goods_sku_list 不传，代表全部发货
			update_send_time, // 是否更新发货时间
			oper_uid: uid, // 操作员id
			send_sms, // 是否发送短信
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 修改订单价格（商家改价，属于商家优惠）
	 * @url admin/business/sys.order.updatePrice 前端调用的url参数地址
	 */
	updatePrice: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id, // 订单id
			goods_sku_list, // 商品信息
			business_discount_express_amount, // 商家优惠的运费金额
			paymentAmount = 0, // 订单实付金额（校验用）
			businessDiscountAmount = 0, // 商家优惠金额（校验用）
		} = data;
		if (!business_discount_express_amount) business_discount_express_amount = 0;
		if (vk.pubfn.isNull(_id)) return { code: -1, msg: "订单ID不能为空" };
		if (vk.pubfn.isNull(goods_sku_list)) return { code: -1, msg: "参数错误" };

		let orderInfo = await vk.daoCenter.orderDao.findById(_id);
		if (vk.pubfn.isNull(orderInfo)) return { code: -1, msg: "订单不存在" };
		if (orderInfo.status !== 0) return { code: -1, msg: "只能修改未付款的订单" };

		let orderBusinessDiscountDiff = 0; // 修改后订单商家合计优惠与修改前的差值
		let orderBusinessExpressDiscountDiff = 0; // 修改后订单商家合计优惠与修改前的差值
		// 循环订单中的商品
		for (let i = 0; i < orderInfo.goods_sku_list.length; i++) {
			let item1 = orderInfo.goods_sku_list[i];
			let item2 = vk.pubfn.getListItem(goods_sku_list, "_id", item1._id);
			if (!item1.business_discount_amount || item1.business_discount_amount < 0) item1.business_discount_amount = 0;
			if (!item2.business_discount_amount || item2.business_discount_amount < 0) item2.business_discount_amount = 0;
			// 本次修改的差值 = 修改后商家优惠 - 修改前商家优惠
			let updateDiff = item2.business_discount_amount - item1.business_discount_amount;
			if (updateDiff !== 0) {
				item1.business_discount_amount += updateDiff; // 修改对应的sku商家优惠金额
				item1.total_discount += updateDiff; // 增加对应的sku合计优惠金额
				item1.should_payment_amount -= updateDiff; // 应付金额减去差值
				orderBusinessDiscountDiff += updateDiff; // 增加本次订单商家优惠总金额
			}
			// 计算该sku优惠后的实际单价 = 应付金额 / 购买数量
			item1.real_price = vk.pubfn.toDecimal(item1.should_payment_amount / item1.buy_num, 0);
		}
		if (!orderInfo.discount_info.business_discount_express_amount) orderInfo.discount_info.business_discount_express_amount = 0;
		// 运费优惠差值
		orderBusinessExpressDiscountDiff = business_discount_express_amount - orderInfo.discount_info.business_discount_express_amount;
		if (orderBusinessExpressDiscountDiff !== 0) {
			orderBusinessDiscountDiff += orderBusinessExpressDiscountDiff;
			orderInfo.amount_info.express_amount -= orderBusinessExpressDiscountDiff;
		}
		console.log('orderBusinessDiscountDiff: ', orderBusinessDiscountDiff)
		console.log('orderBusinessExpressDiscountDiff: ', orderBusinessExpressDiscountDiff)
		// 如果差值=0，代表无修改，则不需要再执行修改数据库操作
		if (orderBusinessDiscountDiff === 0) {
			return { code: -1, msg: "修改失败，商家优惠金额无变动！" };
		}
		if (!orderInfo.discount_info.business_discount_amount) orderInfo.discount_info.business_discount_amount = 0;
		if (!orderInfo.discount_info.total_discount) orderInfo.discount_info.total_discount = 0;
		// 修改订单金额数据
		orderInfo.discount_info.business_discount_amount += (orderBusinessDiscountDiff - orderBusinessExpressDiscountDiff); // 修改订单商家优惠（加上本次优惠差值）
		orderInfo.discount_info.total_discount += orderBusinessDiscountDiff; // 修改订单合计优惠（加上本次优惠差值）
		orderInfo.amount_info.should_payment_amount -= orderBusinessDiscountDiff; // 修改订单应付金额（减去本次优惠差值）
		orderInfo.amount_info.need_payment_amount -= orderBusinessDiscountDiff; // 修改订单还需支付金额（减去本次优惠差值）
		// 计算订单实际折扣 0.5 代表 5折
		orderInfo.discount_info.real_discount = vk.pubfn.toDecimal((orderInfo.amount_info.should_payment_amount - orderInfo.amount_info.express_amount) / orderInfo
			.amount_info.goods_amount, 2);
		if (orderInfo.discount_info.business_discount_amount !== businessDiscountAmount) {
			return { code: -1, msg: "商家减价金额错误", business_discount_amount: orderInfo.discount_info.business_discount_amount, businessDiscountAmount };
		}
		if (orderInfo.amount_info.should_payment_amount !== paymentAmount) {
			return { code: -1, msg: "订单应付金额错误", should_payment_amount: orderInfo.amount_info.should_payment_amount, paymentAmount };
		}
		let dataJson = {
			goods_sku_list: _.set(orderInfo.goods_sku_list), // 覆盖新的商品数据
			"discount_info.business_discount_express_amount": business_discount_express_amount, // 订单商家优惠运费金额
			"discount_info.business_discount_amount": vk.pubfn.toDecimal(orderInfo.discount_info.business_discount_amount, 0), // 订单商家优惠商品金额
			"discount_info.total_discount": vk.pubfn.toDecimal(orderInfo.discount_info.total_discount, 0), // 订单合计优惠
			"discount_info.real_discount": orderInfo.discount_info.real_discount, // 订单最终商品折扣
			"amount_info.express_amount": vk.pubfn.toDecimal(orderInfo.amount_info.express_amount, 0), // 订单运费
			"amount_info.should_payment_amount": vk.pubfn.toDecimal(orderInfo.amount_info.should_payment_amount, 0), // 订单应付
			"amount_info.need_payment_amount": vk.pubfn.toDecimal(orderInfo.amount_info.need_payment_amount, 0), // 订单还需付款
		};
		orderInfo = await vk.daoCenter.orderDao.updateAndReturn({
			whereJson: {
				_id
			},
			dataJson
		});
		res.orderInfo = orderInfo;
		res.orderBusinessDiscountDiff = orderBusinessDiscountDiff;
		res.goods_sku_list = orderInfo.goods_sku_list;
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 获取订单的最新退款信息
	 * @url admin/business/sys.order.getRefundOrder 前端调用的url参数地址
	 */
	getRefundOrder: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id, // 订单id
		} = data;

		let orderRefundInfo = await vk.daoCenter.orderRefundDao.findByWhereJson({
			order_id: _id,
			status: 0
		});
		res.info = orderRefundInfo;
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 订单退款审核
	 * @url admin/business/sys.order.orderRefundExamine 前端调用的url参数地址
	 */
	orderRefundExamine: async function(data) {
		let res = { code: 0, msg: '' };
		let { uid } = this.getClientInfo();
		// 业务逻辑开始-----------------------------------------------------------

		let {
			_id, // 订单id
			type, // 1 同意退款 2 拒绝退款
			out_refund_no, // 退款单号
			goods_list, // 退款商品数量和金额信息
			refund_express_amount, // 运费退款金额
			status_msg, // 退款说明
		} = data;

		// 参数非空检测
		let nullKey = vk.pubfn.isNullOneByObject({ _id, type, out_refund_no, goods_list });
		if (nullKey) return { code: -1, msg: '参数 ' + nullKey + ' 不能为空' };

		res = await vk.daoCenter.orderDao.orderRefundExamine({
			order_id: _id, // 订单id
			oper_uid: uid, // 操作人uid
			type, // 1 同意退款 2 拒绝退款
			out_refund_no, // 退款单号
			goods_list, // 退款商品数量和金额信息
			refund_express_amount, // 运费退款金额
			status_msg, // 退款说明
		});

		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 订单交易设置
	 * @url admin/business/sys.order.updateOrderSetting 前端调用的url参数地址
	 */
	updateOrderSetting: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------
		let {
			order,
			order_refund,
			refund_address,
		} = data;
		await vk.daoCenter.mchDao.updateMy({
			order: _.set(order),
			order_refund: _.set(order_refund),
			refund_address: _.set(refund_address),
		});
		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
	/**
	 * 商家主动订单退款
	 * @url admin/business/sys.order.businessOrderRefund 前端调用的url参数地址
	 */
	businessOrderRefund: async function(data) {
		let res = { code: 0, msg: '' };
		let { uid } = this.getClientInfo();
		// 业务逻辑开始-----------------------------------------------------------
		let {
			_id, // 订单id
			goods_list, // 退款商品列表
			refund_express_amount, // 退款运费
			status_msg, // 退款备注
		} = data;
		/*
		 * 数据格式示例
		 {
			"_id": "ca780ad56309de07128b868725ab9249",
			"refund_express_amount": 800,
			"status_msg": "",
			"goods_list": [
				{
					"_id":"001-1",
					"refund_num": 1,
					"refund_amount": 10000,
				}
			]
		} */
		let mchInfo = await vk.daoCenter.mchDao.find();
		let orderInfo = await vk.daoCenter.orderDao.findById(_id);

		// 添加退款申请单
		res = await vk.daoCenter.orderDao.applyRefund({
			mchInfo,
			orderInfo,
			oper_type: "business",
			oper_uid: uid,
			refund_reason:"商家主动退款",
			refund_desc:status_msg,
			goods_sku_list: goods_list,
			is_auto_refund: 1, // 1 自动审核通过
		});

		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},

	/**
	 * 模板函数
	 * @url admin/business/sys.order.test 前端调用的url参数地址
	 */
	test: async function(data) {
		let res = { code: 0, msg: '' };
		// 业务逻辑开始-----------------------------------------------------------


		// 业务逻辑结束-----------------------------------------------------------
		return res;
	},
};

module.exports = cloudObject;
